import { autoprefix, dec } from "./utils";
import { flipMethods } from "./flipMethods";
import { turnMethods } from "./turnMethods";

(function ($) {
  "use strict";

  // Extend $.fn

  $.extend($.fn, {
    flip: function () {
      return dec($(this[0]), flipMethods, arguments);
    },

    turn: function () {
      return dec($(this[0]), turnMethods, arguments);
    },

    transform: function (transform, origin) {
      var properties = { transform };

      if (origin) properties["transform-origin"] = origin;

      return this.css(autoprefix(properties));
    },

    animatef: function (point) {
      var data = this.data();

      if (data.effect) data.effect.stop();

      if (point) {
        if (!point.to.length) point.to = [point.to];
        if (!point.from.length) point.from = [point.from];

        var diff = [],
          len = point.to.length,
          animating = true,
          that = this,
          time = new Date().getTime(),
          frame = function () {
            if (!data.effect || !animating) return;

            var v = [],
              timeDiff = Math.min(point.duration, new Date().getTime() - time);

            for (var i = 0; i < len; i++)
              v.push(
                data.effect.easing(
                  1,
                  timeDiff,
                  point.from[i],
                  diff[i],
                  point.duration
                )
              );

            point.frame(len == 1 ? v[0] : v);

            if (timeDiff == point.duration) {
              delete data["effect"];
              that.data(data);
              if (point.complete) point.complete();
            } else {
              requestAnimationFrame(frame);
            }
          };

        for (var i = 0; i < len; i++) diff.push(point.to[i] - point.from[i]);

        data.effect = $.extend(
          {
            stop: function () {
              animating = false;
            },
            easing: function (x, t, b, c, data) {
              return c * Math.sqrt(1 - (t = t / data - 1) * t) + b;
            },
          },
          point
        );

        this.data(data);

        frame();
      } else {
        delete data["effect"];
      }
    },
  });
})(window.jQuery);
